import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { Observable } from 'rxjs';
import { IS_SKIP_AUTH } from 'src/decorators/skipAuth';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  handleRequest<TUser = any>(
    err: any,
    user: any,
    info: any,
    context: ExecutionContext,
    status?: any,
  ): TUser {
    if (info?.name === 'TokenExpiredError') {
      throw new UnauthorizedException('登录已过期，请重新登录');
    }
    if (info?.name === 'JsonWebTokenError') {
      throw new UnauthorizedException('无效登录信息，请重新登录');
    }
    if (err || !user) {
      throw new UnauthorizedException('请重新登录');
    }
    return user;
  }

  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const isSkipAuth = this.reflector.getAllAndOverride<boolean>(IS_SKIP_AUTH, [
      context.getHandler(),
      context.getClass(),
    ]);
    // isSkipAuth 为 true 直接通过认证守卫，否则调用 super.canActivate(context) → 执行正常的 JWT 鉴权流程
    if (isSkipAuth) {
      return true;
    }
    return super.canActivate(context);
  }
}
